﻿using System.Collections.Generic;
using IQIGame.Onigao.Framework;
using IQIGame.Onigao.GamePlay;

namespace IQIGame.Onigao.Logic
{
    public class ShieldController
    {
        public BuffComponent self;
        public ShieldController(BuffComponent rTarget)
        {
            this.self = rTarget;
        }

        private int mCurShield;

        /// <summary>
        /// 当前护盾值
        /// </summary>
        public int curShield
        {
            get => this.mCurShield;
            private set
            {
                if (this.mCurShield != value)
                {
                    this.mCurShield = value;
                    var rResultCtrl = this.self.unit.battle.playCtrl.resultCtrl;
                    var rPOD = BattleUpdateFactory.CreateUnitShield(this.self.unit.GUID, this.curShield);
                    rResultCtrl.Add(rPOD);
                }
            }
        }

        private List<Shield> shields = new List<Shield>();
        private Dictionary<uint, Shield> shieldDict = new Dictionary<uint, Shield>();
        private uint shieldID = 1;

        List<Shield> rRemoveList = new List<Shield>();

        public uint AddShield(int nShield, int nDuration = 0)
        {
            var rShield = ClassPool.Get<Shield>();
            rShield.uid = ++this.shieldID;
            rShield.left = nShield;
            this.curShield += nShield;
            this.shields.Add(rShield);
            this.shieldDict.TryAdd(rShield.uid, rShield);
            return rShield.uid;
        }

        public void RemoveShield(uint uid)
        {
            if (this.shieldDict.TryGetValue(uid, out var rShield))
            {
                if (rShield.left > 0)
                {
                    this.curShield -= rShield.left;
                }
                this.shieldDict.Remove(uid);
                this.shields.Remove(rShield);
                ClassPool.Put(rShield);
            }
        }

        public int Damage(int nDamage)
        {
            if (nDamage >= this.curShield)
            {
                this.mCurShield = 0;
                this.shields.Clear();
                this.shieldDict.Clear();
                return nDamage - this.curShield;
            }

            for (int i = 0; i < this.shields.Count; i++)
            {
                var rShield = this.shields[i];
                if (rShield.left > nDamage)
                {
                    rShield.left -= nDamage;
                    nDamage = 0;
                    break;
                }

                nDamage -= rShield.left;
                rShield.left = 0;
            }

            this.curShield -= nDamage;
            return 0;
        }

        public class Shield : IReusableClass
        {
            public uint uid;
            public int left;

            public uint MaxStore => 3;

            public void OnReset()
            {
                this.uid = 0;
                this.left = 0;
            }
        }

    }
}